技巧89 在pod内访问Kubernetes API

通常,pod有可能彼此完全独立地运行,甚至可以不知道它们是作为Kubernetes集群的一部分运行的。但是,Kubernetes确实提供了丰富的API,并且使容器能够访问它,这为自检和适应性行为以及容器自行管理Kubernetes集群的能力打开了大门。

问题

想要在pod内访问Kubernetes API。

解决方案

使用 curl 从pod中的容器中访问Kubernetes API,使用可用于容器的授权信息。

这是本书中较为简短的技巧之一,但其中包含很多要学习的内容。这是它成为要学习的一种有用的技巧的原因之一。除此之外,我们将介绍:

  • kubectl 命令;
  • 启动Kubernetes pod;
  • 访问Kubernetes pod;
  • 一个Kubernetes反模式;
  • 不记名令牌(bearer token);
  • Kubernetes密文;
  • Kubernetes“向下的API”。
1.没有Kubenetes集群?

如果无权访问Kubernetes集群,可以有几个选择。有许多云提供商提供按需付费的Kubernetes集群。不过,为了使依赖性降到最低,我们建议使用Minikube(技巧88中已提到),它不需要信用卡。

有关如何安装Minikube的信息,参见Kubernetes官方网站上的文档。

2.创建pod

首先,我们将使用 kubectl 命令在新的 ubuntu pod 中创建一个容器,然后在命令行上访问该容器中的shell,如代码清单12-2所示。( kubectl run 目前在pod和容器之间是一对一的关系,尽管pod通常比容器更灵活。)

代码清单12-2 创建并设置容器

$ kubectl run -it ubuntu --image=ubuntu:16.04 --restart=Never  ⇽--- 使用-ti标志来运行kubectl命令,给pod命名为“ubuntu”,使用当前还算熟悉的ubuntu:16.04镜像,并且告知Kubernetes在pod/容器已经存在的时候不要重启
 If you don't see a command prompt, try pressing enter.   ⇽---  Kubectl告知你终端在你没有按回车键之前可能没有展示提示符
 root@ubuntu:/# apt-get update -y && apt-get install -y curl  ⇽--- 在你按回车键后,这是容器内的提示符,我们会升级容器的打包系统,安装curl
 [...]
root@ubuntu:/   ⇽--- 一旦安装完成,提示符会返回

现在,我们位于由 kubectl 命令创建的容器中,并确保已安装curl。从pod访问Kubenetes API的方法如代码清单12-3所示。

警告

从shell访问和修改pod被视为Kubernetes反模式。我们在这里使用它来演示在pod内可能发生的事情,而不是如何使用pod。

代码清单12-3 从pod访问Kubenetes API

root@ubuntu:/# $ curl -k -X GET \  ⇽--- 使用curl命令来获取Kubernetes API。-k标志允许curl无须在客户端部署的证书即可工作,和API交互的HTTP方法通过-X标志指定为GET
   -H "Authorization: Bearer \  ⇽--- -H标志给请求添加了HTTP协议头。这个是简短讨论过的授权令牌
   $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" <3> \
  https://${KUBERNETES_PORT_443_TCP_ADDR}:${KUBERNETES_SERVICE_PORT_HTTPS}  ⇽--- 访问的URL地址通过pod内的环境变量构建而成
 {
  "paths": [  ⇽---  API的默认返回值列出了可供消费的路径
    "/api",
    "/api/v1",
    "/apis",
    "/apis/apps",
    "/apis/apps/v1beta1",
    "/apis/authentication.k8s.io",
    "/apis/authentication.k8s.io/v1",
    "/apis/authentication.k8s.io/v1beta1",
    "/apis/authorization.k8s.io",
    "/apis/authorization.k8s.io/v1",
    "/apis/authorization.k8s.io/v1beta1",
    "/apis/autoscaling",
    "/apis/autoscaling/v1",
    "/apis/autoscaling/v2alpha1",
    "/apis/batch",
    "/apis/batch/v1",
    "/apis/batch/v2alpha1",
    "/apis/certificates.k8s.io",
    "/apis/certificates.k8s.io/v1beta1",
    "/apis/extensions",
    "/apis/extensions/v1beta1",
    "/apis/policy",
    "/apis/policy/v1beta1",
    "/apis/rbac.authorization.k8s.io",
    "/apis/rbac.authorization.k8s.io/v1alpha1",
    "/apis/rbac.authorization.k8s.io/v1beta1",
    "/apis/settings.k8s.io",
    "/apis/settings.k8s.io/v1alpha1",
    "/apis/storage.k8s.io",
    "/apis/storage.k8s.io/v1",
    "/apis/storage.k8s.io/v1beta1",
    "/healthz",
    "/healthz/ping",
    "/healthz/poststarthook/bootstrap-controller",
    "/healthz/poststarthook/ca-registration",
    "/healthz/poststarthook/extensions/third-party-resources",
    "/logs",
    "/metrics",
    "/swaggerapi/",
    "/ui/",
    "/version"
  ]
}
root@ubuntu:/# curl -k -X GET -H "Authorization: Bearer $(cat  ⇽--- 
➥ /var/run/secrets/kubernetes.io/serviceaccount/token)"
➥ https://${KUBERNETES_PORT_443_TCP_ADDR}:
➥ ${KUBERNETES_SERVICE_ORT_HTTPS}/version  ⇽--- 发起了另一个请求,这次是/version路径
 {
  "major": "1",
  "minor": "6",  ⇽--- /version请求的返回值指定了正在运行的Kubernetes的版本
  "gitVersion": "v1.6.4",
  "gitCommit": "d6f433224538d4f9ca2f7ae19b252e6fcb66a3ae",
  "gitTreeState": "dirty",
  "buildDate": "2017-06-22T04:31:09Z",
  "goVersion": "go1.7.5",
  "compiler": "gc",
  "platform": "linux/amd64"
}

代码清单12-3中涵盖了许多新材料,但我们希望它给人一种无须任何设置即可动态地在Kubernetes pod中完成工作的感觉。

从代码清单12-3中获取的关键点是,该信息对pod内的用户可用,使pod可以与Kubernetes API联系。这些信息项统称为“向下的API”。目前,向下的API包括两类数据:环境变量和公开给pod的文件。

前面的示例中使用了一个文件来向Kubernetes API提供身份验证令牌。该令牌在/var/run/secrets/kubernetes.io/serviceaccount/token文件中可用。在代码清单12-3中,这一文件通过 cat 运行,并且 cat 命令的输出被作为 Authorization 的一部分——HTTP首部提供。这一首部指定所使用的授权属于 Bearer (不记名)类型,并且不记名令牌是 cat 的输出,因此 curl-H 参数如下所示:

-H "Authorization: Bearer
➥ $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)"

注意

不记名令牌是仅需要给予特定令牌而不需要其他认证(如用户名/密码)的验证方式。不记名股票的操作遵循类似的原则,即股票的持有者是有权出售股票的人。

向下的API项是Kubernetes“密文”的一种形式。可以使用Kubernetes API创建任何密文,并通过pod中的文件公开。这种机制允许将密文与Docker镜像和Kubernetes pod或部署配置分开,这意味着可以将权限与那些更开放的项目分开处理。

讨论

本技巧值得关注,因为它涉及很多背景知识。要掌握的关键点是,Kubernetes pod提供了允许它们与Kubernetes API进行交互的信息。这使应用程序可以在Kubernetes中运行,以监视集群中发生的活动并对其进行操作。例如,你可能有一个基础设施pod,可以监视新涌现的pod的API,调查其活动并在其他地方记录数据。

尽管基于角色的访问控制(role based access control,RBAC)不在本书的讨论范围内,但是值得一提的是,这对安全性是有影响的,因为你不一定希望集群中的任何用户都具有这种访问级别。因此,API的某些部分将不仅仅需要不记名令牌来获得访问权限。

这些与安全性相关的考虑因素使本技巧一半与Kubernetes相关,一半与安全相关。无论哪种方式,对于希望“真正”使用Kubernetes的人来说,这都是一项重要的技巧,可以帮助他们了解API的工作方式以及它可能如何被滥用。

results matching ""

    No results matching ""